package cn.semcorp.zhuhaizj.services.impl;

import cn.semcorp.zhuhaizj.common.Common;
import cn.semcorp.zhuhaizj.mapper.AccountingMapper;
import cn.semcorp.zhuhaizj.pojo.dto.AccountingUpdateChinese;
import cn.semcorp.zhuhaizj.pojo.dto.InsertInputOutputDTO;
import cn.semcorp.zhuhaizj.pojo.dto.SelectMaterialsDTO;
import cn.semcorp.zhuhaizj.pojo.vo.*;
import cn.semcorp.zhuhaizj.repo.IRedisRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AccountingServiceImpl {

    @Autowired
    private AccountingMapper accountingMapper;


    /**
     * 添加非量产
     */
    public String addIsMassProduct(String materials){
        int row = accountingMapper.repeatIsMass(materials);
        if (row == 0){
            accountingMapper.addIsMassProduct(materials);
            return "物料名称:"+materials+",添加成功!";
        }
        return "物料名称:"+materials+",已存在!";
    }

    /**
     * 上传导入 - 原料/混合料
     */
    public void upLoadNormal(List<AccountingUpdateChinese> list){
        List<String> nonmass = accountingMapper.selectNonMassList();

        for (AccountingUpdateChinese acc : list) {
            // 车间
            acc.setWorkshop(Common.getWorkByWarehouse(acc.getWarehouseCode()));
            // 日期
            acc.setDate(Common.getNowDateString());
            // 原料状态
            acc.setState(Common.materialsIsNormal(acc.getUseDate()));
            // 有效期天数
            acc.setExpirationDate(Common.howManyDaysBetween(acc.getUseDate(),Common.getNowDateString()));
            // 物料类型
            acc.setMaterialModel(Common.whatIsMaterialsModel(acc.getMaterialName()));
            // 是否量产
            acc.setIsMassProduction("量产");
            for (String s : nonmass) {
                if (s.equals(acc.getMaterialName())){
                    acc.setIsMassProduction("非量产");
                    break;
                }
            }
        }
        accountingMapper.insertList(list);
    }

    /**
     * 追加导入 - 原料/混合料
     */
    public void upLoadAbnormal(List<AccountingUpdateChinese> list,String date){
        List<String> nonmass = accountingMapper.selectNonMassList();
        for (AccountingUpdateChinese acc : list) {
            // 车间
            acc.setWorkshop(Common.getWorkByWarehouse(acc.getWarehouseCode()));
            // 日期
            acc.setDate(date);
            // 原料状态
            acc.setState(Common.materialsIsNormal(acc.getUseDate()));
            // 有效期天数
            acc.setExpirationDate(Common.howManyDaysBetween(acc.getUseDate(),Common.getNowDateString()));
            // 物料类型
            acc.setMaterialModel(Common.whatIsMaterialsModel(acc.getMaterialName()));
            // 是否量产
            acc.setIsMassProduction("量产");
            for (String s : nonmass) {
                if (s.equals(acc.getMaterialName())){
                    acc.setIsMassProduction("非量产");
                    break;
                }
            }
        }
        accountingMapper.insertList(list);
    }

    /**
     * 混合涂布料
     * @param workshop
     * @return
     */
    public Map<String,List<MixturesVO>> queryMixtures(String workshop,String model){
        Map<String,List<MixturesVO>> map = new HashMap<>();
        String start = String.valueOf(Common.getNowDate());
        String end = String.valueOf(Common.getBefore3TenNowDate());

        // 物料名称
        List<String> dateList = Common.getAllDatesBetweenTwoDates(Common.getBefore3TenNowDate(),Common.getNowDate());
        List<AccountingVO> list = accountingMapper.selectMaterials(start, end, workshop, model);
        if (list.size() == 0){
            return map;
        }

        List<String> distinctList = list.stream().map(AccountingVO::getMaterialName)
                .distinct()
                .collect(Collectors.toList());

        for (String name : distinctList) {
            List<MixturesVO> a1List = new ArrayList<>();
            for (String date : dateList) {
                MixturesVO a1 = new MixturesVO();
                double quantity = 0 ;
                for (AccountingVO accountingVO : list) {
                    if (accountingVO.getMaterialName().equals(name) && accountingVO.getDate().equals(date) &&
                    Common.isNumber(accountingVO.getQuantity())){
                        quantity += Double.parseDouble(accountingVO.getQuantity());
                    }
                }

                if (quantity == 0){
                    a1.setDate(date);
                    a1.setQuantity("-");
                    a1List.add(a1);
                    map.put(name,a1List);
                    continue;
                }
                a1.setDate(date);
                a1.setQuantity(Common.transformTwoNumber(quantity));
                a1List.add(a1);
            }
            map.put(name,a1List);
        }
        return map;
    }


    /**
     * 涂布混合料
     * @param workshop
     * @return
     */
    public Map<String,List<MaterialsVO>> queryMaterials(String workshop,String model){
        Map<String,List<MaterialsVO>> map = new HashMap<>();
        String start = String.valueOf(Common.getNowDate());
        String end = String.valueOf(Common.getBefore3TenNowDate());
        List<String> dateList = Common.getAllDatesBetweenTwoDates(Common.getBefore3TenNowDate(),Common.getNowDate());
        // 根据车间查询
        List<AccountingVO> list = accountingMapper.selectMixtures(start, end, workshop,model);
        List<String> distinctList = list.stream().map(AccountingVO::getMaterialName)
                .distinct()
                .collect(Collectors.toList());
        for (String name : distinctList) {
            List<MaterialsVO> a1List = new ArrayList<>();
            for (String date : dateList) {
                MaterialsVO a1 = new MaterialsVO();
                double quantity = 0 ;
                for (AccountingVO accountingVO : list) {
                    if (accountingVO.getMaterialName().equals(name) && accountingVO.getDate().equals(date)){
                        quantity += Double.parseDouble(accountingVO.getQuantity());
                    }
                }

                if (quantity == 0){
                    a1.setDate(date);
                    a1.setQuantity("-");
                    a1List.add(a1);
                    map.put(name,a1List);
                    continue;
                }
                a1.setDate(date);
                a1.setQuantity(Common.transformTwoNumber(quantity));
                a1List.add(a1);
            }
            map.put(name,a1List);
        }
        return map;
    }


    /**
     * 报废
     */
//    public void up() {
//        EasyExcel.read("/Users/woaini/Desktop/库存.xlsx",AccountingUploadDTO.class,new ReadAccountingUploadDTODateListener())
//                .sheet("数据").doRead();
//        List<AccountingUploadDTO> accountingList = ReadAccountingUploadDTODateListener.getAccountingList();
//        accountingMapper.insert(accountingList);
//    }

    /**
     * 辅助 - 是否量产
     */
    public String isMassByMaterials(String materials, List<String> list){
        if (materials == null){
            return "";
        }
        if (list.contains(materials)){
            return "非量产";
        }
        return "量产";
    }

    public Map<String,List<CommonVO>> queryMaterialsUtilization(SelectMaterialsDTO dto) {
        String[] workshopList = dto.getWorkshop().split(",",-1);
        String slurryName = dto.getSlurryName();
        String tickNumber = dto.getTickNumber();
        Map<String,List<CommonVO>> map = new HashMap<>();
        double d1 = 0;
        double d2 = 0;
        CommonVO v = null;
        Map<String, String> uniqueValuesMap = new HashMap<>();
        List<String> uniqueList = new ArrayList<>();
        List<MaterialsUtilizationVO> list1 = new ArrayList<>();
        for (String workshop : workshopList){
            if (workshop.equals("")){
                continue;
            }
            List<CommonVO> result = new ArrayList<>();
            // 日期范围查询
            if (dto.getStart() != null || dto.getEnd() != null){
                LocalDate start = LocalDate.parse(dto.getStart());
                LocalDate end = LocalDate.parse(dto.getEnd());
                // 按日期范围查询天利用
                List<String> days = Common.getAllDatesBetweenTwoDates(start, end);
                // 包括 原料领用重量  入库重量 日期 浆料标签(唯一)    所有日期范围里的记录
                for (String day : days) {
                    v = new CommonVO();
                    v.setD1(day);
                    d1 = 0 ;
                    d2 = 0 ;
                    list1 = accountingMapper.queryMaterialsUtilizationByRange(workshop,slurryName,tickNumber,day);
                    if (list1 == null || list1.size() == 0){
                        v.setS2("-");
                        result.add(v);
                        continue;
                    }
                    for (MaterialsUtilizationVO vo : list1) {
                        d1 += Double.parseDouble(vo.getStart());
                    }

                    uniqueValuesMap = list1.stream()
                            .collect(Collectors.toMap(
                                    MaterialsUtilizationVO::getLabel,  // Key
                                    MaterialsUtilizationVO::getEnd,  // Value
                                    (value1, value2) -> value1 // 处理冲突策略
                            ));
                    uniqueList = new ArrayList<>(uniqueValuesMap.values());
                    for (String ends : uniqueList) {
                        d2 += Double.parseDouble(ends);
                    }
                    v.setS2(Common.transformTwoNumber(d2/d1*100));
                    result.add(v);
                }
                map.put(workshop,result);
            }else{
                // 月查询
                List<String> mathMonth = Common.getLastSixMonthsInYYYYMMFormat();
                for (String yearMonth : mathMonth) {
                    d1 = 0 ;
                    d2 = 0 ;
                    v = new CommonVO();
                    v.setD1(yearMonth);
                    list1 = accountingMapper.queryMaterialsUtilizationByMonth(yearMonth,workshop,slurryName,tickNumber);
                    if (list1 == null || list1.size() == 0){
                        v.setS2("-");
                        result.add(v);
                        continue;
                    }
                    for (MaterialsUtilizationVO utilizationVO : list1) {
                        d1 += Double.parseDouble(utilizationVO.getStart());
                    }
                    uniqueValuesMap = list1.stream()
                            .collect(Collectors.toMap(
                                    MaterialsUtilizationVO::getLabel,  // Key
                                    MaterialsUtilizationVO::getEnd,  // Value
                                    (value1, value2) -> value1 // 处理冲突策略
                            ));
                    uniqueList = new ArrayList<>(uniqueValuesMap.values());
                    for (String ends : uniqueList) {
                        d2 += Double.parseDouble(ends);
                    }
                    v.setS2(Common.transformTwoNumber(d2/d1*100));
                    result.add(v);
                }
                map.put(workshop,result);
            }
        }
        return map;
    }

    public void insertInputOutput(List<InsertInputOutputDTO> list) {
        accountingMapper.insertInputOutput(list);
    }

    /**
     * 存入redis
     * @return
     */
    @Autowired
    private IRedisRepository redisRepository;
    public List<String> selectWorkshop() {
/*        log.info("正在执行查询原料车间类型业务...");
        List<String> list = redisRepository.getMaterialWorkshopList();
        if (list.size() != 0){
            log.info("查询原料车间类型Redis缓存命中,返回成功!");
            return list;
        }
        log.info("查询执行原料车间类型Redis缓存命中失败,正在执行查询Mysql业务...");*/
        List<String> strings = accountingMapper.selectWorkshopList();
/*        log.info("查询原料车间类型Mysql业务执行成功,正在执行存入Redis业务...");
        redisRepository.saveMaterialWorkshopList(strings);
        log.info("查询原料车间类型存入Redis业务执行成功!");*/
        return strings;
    }
}
